use actix_web::{Responder, HttpResponse, HttpRequest, Error};
use futures::future::{ready, Ready};
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
use rbatis::crud::CRUD;
use rbatis::rbatis::Rbatis;
use bigdecimal::BigDecimal;
use rbatis::Error as rError;

#[crud_table( id_name:id |  id_type:String |  table_name:freight_template |  table_columns:id,billing_rule,province_id,unified_price,regional_price,details,create_time,update_time,delete_flag )]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct FreightTemplate{
    pub id: Option<String>,
    pub billing_rule: Option<i32>,
    pub province_id: Option<String>,
    pub unified_price: Option<BigDecimal>,
    pub regional_price: Option<BigDecimal>,
    pub details: Option<String>,
    pub create_time: Option<NaiveDateTime>,
    pub update_time: Option<NaiveDateTime>,
    pub delete_flag: Option<i32>,
}

impl Responder for FreightTemplate {
    type Error = Error;
    type Future = Ready<Result<HttpResponse, Error>>;

    fn respond_to(self, _req: &HttpRequest) -> Self::Future {
        let body = serde_json::to_string(&self).unwrap();

        // Create response and set content type
        ready(Ok(HttpResponse::Ok()
            .content_type("application/json")
            .body(body)))
    }
}

pub async fn new_freight_template() -> FreightTemplate{
    FreightTemplate{
        id: None,
        billing_rule: None,
        province_id: None,
        unified_price: None,
        regional_price: None,
        details: None,
        create_time: None,
        update_time: None,
        delete_flag: None
    }
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct FreightInfo{
    pub good_id: Option<String>,
    pub province_id: Option<String>,
    pub freight_template_id: Option<String>,
    pub billing_rule: Option<i32>,
    pub unified_price: Option<BigDecimal>,
    pub regional_price: Option<BigDecimal>,
}

impl Responder for FreightInfo {
    type Error = Error;
    type Future = Ready<Result<HttpResponse, Error>>;

    fn respond_to(self, _req: &HttpRequest) -> Self::Future {
        let body = serde_json::to_string(&self).unwrap();

        // Create response and set content type
        ready(Ok(HttpResponse::Ok()
            .content_type("application/json")
            .body(body)))
    }
}

impl FreightTemplate{
    #[sql(rbatis, "select g.id as good_id, ft.province_id, ft.id as freight_template_id, ft.billing_rule, ft.unified_price, ft.regional_price from good g
                    inner join freight_template ft on ft.id = g.freight_template_id
                    where g.id = ?
                    and ft.province_id = (select a.province_id
                                            from `user` u
                                            inner join address a on a.id = u.default_address_id
                                            where u.id = ?)")]
    pub async fn find_freight_info(&self, rbatis: &Rbatis, good_id :&String, user_id :&String) -> Result<FreightInfo, rError>{}
}